package com.example.health_life.service;

import com.example.health_life.dao.Order;
import com.example.health_life.dao.OrderRepository;
import com.example.health_life.dao.Orderitem;
import com.example.health_life.dao.OrderitemRepository;
import com.example.health_life.dao.Product;
import com.example.health_life.dao.ProductRepository;
import com.example.health_life.dto.OrderItemDetailDTO;
import com.example.health_life.dto.OrderWithItemsDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderRepository orderRepository;

    @Autowired
    private OrderitemRepository orderitemRepository;

    @Autowired
    private ProductRepository productRepository;

    @Override
    public List<Order> getOrderList(Integer userId, Byte status, String postalCode) {
        if (userId != null && status != null && postalCode != null) {
            return orderRepository.findByUserIdAndStatus(userId, status).stream()
                    .filter(order -> postalCode.equals(order.getPostalCode()))
                    .toList();
        } else if (userId != null && postalCode != null) {
            return orderRepository.findByUserIdAndPostalCode(userId, postalCode);
        } else if (userId != null && status != null) {
            return orderRepository.findByUserIdAndStatus(userId, status);
        } else if (userId != null) {
            return orderRepository.findByUserId(userId);
        } else if (status != null) {
            return orderRepository.findByStatus(status);
        } else if (postalCode != null) {
            return orderRepository.findByPostalCode(postalCode);
        } else {
            return orderRepository.findAll();
        }
    }

    @Override
    public Order getOrderById(Integer id) {
        return orderRepository.findById(id)
                .orElseThrow(() -> new IllegalStateException("订单不存在"));
    }

    @Override
    @Transactional
    public int createOrder(Order order) {
        // 设置创建时间
        order.setCreateTime(java.time.Instant.now());
        // 如果状态为空，设置为购物车状态（0）
        if (order.getStatus() == null) {
            order.setStatus((byte) 0);
        }
        return orderRepository.save(order).getId();
    }

    @Override
    @Transactional
    public int updateOrderStatus(Integer id, Byte status) {
        Order order = orderRepository.findById(id)
                .orElseThrow(() -> new IllegalStateException("订单不存在"));
        
        // 验证状态值是否合法
        if (status < -1 || status > 4) {
            throw new IllegalStateException("无效的订单状态");
        }
        
        order.setStatus(status);

        // 根据状态更新时间字段
        if (status == 1) { // 待付款 -> 设置支付时间 (如果状态为待付款，通常意味着刚刚下单或者从购物车状态变为待付款)
             // 注意：这里通常是指用户支付成功后的状态，具体逻辑可能需要根据业务调整
             // 如果业务含义是"订单已创建，等待支付"，这里不应该设置payTime
             // 如果业务含义是"用户已支付，订单状态更新为待发货"，那么下面的状态判断可能更合适
        } else if (status == 2) { // 待发货 -> 设置支付时间
            order.setPayTime(Instant.now());
        } else if (status == 3) { // 待收货 -> 设置发货时间
            order.setShipTime(Instant.now());
        } else if (status == 4) { // 已完成 -> 设置完成时间
            order.setCompleteTime(Instant.now());
        } else if (status == -1) { // 已取消 -> 不设置时间，或者设置取消时间（如果Order实体有取消时间字段）
            // order.setCancelTime(Instant.now()); // 如果有取消时间字段可以这样设置
        }

        orderRepository.save(order);
        return id;
    }

    @Override
    @Transactional
    public int deleteOrder(Integer id) {
        Order order = orderRepository.findById(id)
                .orElseThrow(() -> new IllegalStateException("订单不存在"));
        
        // 将订单状态设置为取消（-1）
        order.setStatus((byte) -1);
        orderRepository.save(order);
        return id;
    }

    @Override
    @Transactional
    public int updateOrder(Integer id, String address, Double totalPrice, Byte status) {
        Order order = orderRepository.findById(id)
                .orElseThrow(() -> new IllegalStateException("订单不存在"));

        // 更新订单信息
        if (address != null) {
            order.setAddress(address);
        }
        if (totalPrice != null) {
            if (totalPrice <= 0) {
                throw new IllegalStateException("订单总价必须大于0");
            }
            order.setTotalPrice(java.math.BigDecimal.valueOf(totalPrice));
        }
        if (status != null) {
            // 验证状态值是否合法
            if (status < -1 || status > 4) {
                throw new IllegalStateException("无效的订单状态");
            }else{
                if(status == 1){
                    order.setCreateTime( java.time.Instant.now());//设置当前时间为订单创建时间
                }
                if(status == 2){
                    order.setPayTime(java.time.Instant.now());//设置订单支付时间
                }
                if(status == 3){
                    order.setShipTime(java.time.Instant.now());//设置订单发货时间
                }
                if(status == 4){
                    order.setCompleteTime(java.time.Instant.now());//设置订单完成时间
                }
            }
            order.setStatus(status);
        }

        orderRepository.save(order);
        return id;
    }

    @Override
    public List<OrderWithItemsDTO> getOrderListWithItems(Integer userId, Byte status, String postalCode) {
        List<Order> orders;
        if (userId != null) {
            orders = orderRepository.findByUserId(userId);
            if (status != null) {
                orders = orders.stream().filter(o -> status.equals(o.getStatus())).collect(Collectors.toList());
            }
            // Example: If you want to use postalCode from the Order entity (uncomment if Order has postalCode and it's needed)
            // if (postalCode != null && !postalCode.isEmpty()) { 
            // orders = orders.stream().filter(o -> postalCode.equals(o.getPostalCode())).collect(Collectors.toList());
            // }
        } else {
            // Behavior for null userId: return empty or throw error based on requirements.
            // For now, returning empty list if no userId, or you could fetch all orders if appropriate.
            return new ArrayList<>();
        }

        List<OrderWithItemsDTO> result = new ArrayList<>();
        for (Order order : orders) {
            List<Orderitem> orderitems = orderitemRepository.findByOrderId(order.getId());
            List<OrderItemDetailDTO> itemDTOs = new ArrayList<>();
            for (Orderitem item : orderitems) {
                Product product = null;
                if (item.getProductId() != null) { 
                    product = productRepository.findById(item.getProductId())
                                                    .orElse(null); 
                }

                String productName = product != null ? product.getTitle() : "商品信息缺失";
                itemDTOs.add(new OrderItemDetailDTO(
                    item.getProductId(),
                    productName,
                    item.getProductCount(),
                    item.getTotal() 
                ));
            }
            result.add(new OrderWithItemsDTO(order, itemDTOs));
        }
        return result;
    }

    @Override
    @Transactional
    public void hardDeleteOrder(Integer id) {
        if (!orderRepository.existsById(id)) {
            throw new IllegalStateException("订单不存在，无法删除: ID " + id);
        }
        // First, delete associated order items to avoid foreign key constraint violations
        orderitemRepository.deleteByOrderId(id);
        // Then, delete the order itself
        orderRepository.deleteById(id);
    }
}
